home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Windows Expert
/
Windows Expert.iso
/
windownt
/
minrec.zip
/
RECHOOK.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-04-30
|
10KB
|
308 lines
// ************************************************************************
// MODULE : RecHook.C
// PURPOSE :
// FUNCTIONS :
// DllEntryPoint - main DLL entry point
// StartJournalRecord - starts the journal record hook
// StopJournalRecord - stops the journal record hook
// StartJournalPlayback - starts the journal playback hook
// StopJournalPlayback - stops the journal playback hook
// COMMENTS :
// ************************************************************************
#define STRICT
#include <Windows.H>
#include "RecHook.H"
// Internal Defines
// -----------------------------------------------------------------------
#define FILENAME "JOURNAL.BIN" // File used to record/play messages
typedef struct GLOBAL_STRUCT {
BOOL fRecording;
BOOL fPlaying;
BOOL fStopRecording;
BOOL fStopPlaying;
UINT PlayedMsgCount;
UINT RecordedMsgCount;
DWORD BaseMsgTime;
DWORD LastMsgTime;
HFILE hFile;
OFSTRUCT OFStruct;
EVENTMSG EventMsg;
HHOOK hHookRecord;
HHOOK hHookPlayback;
HINSTANCE hInstance;
} GLOBAL, *PGLOBAL;
// Global Data
// -----------------------------------------------------------------------
GLOBAL Global; // various global data
// Internal Function Prototypes
// -----------------------------------------------------------------------
LRESULT CALLBACK JournalRecordProc ( int, WPARAM, LPARAM );
LRESULT CALLBACK JournalPlaybackProc( int, WPARAM, LPARAM );
// ************************************************************************
// FUNCTION : DllEntryPoint( HINSTANCE, DWORD, LPVOID )
// PURPOSE : DllEntryPoint is called by Windows when the DLL is entered
// via a "Process Attach", "Thread Attach", "Thread Detach" or a
// "Process Detach".
// ************************************************************************
BOOL WINAPI
DllEntryPoint( HINSTANCE hInstanceDll, DWORD dwReason, LPVOID lpvReserved )
{
switch( dwReason ) {
case DLL_PROCESS_ATTACH:
Global.fRecording = FALSE;
Global.fPlaying = FALSE;
Global.hInstance = hInstanceDll;
break;
}
return( TRUE );
UNREFERENCED_PARAMETER( lpvReserved );
}
// ************************************************************************
// FUNCTION : StartJournalRecord()
// PURPOSE :
// ************************************************************************
VOID WINAPI
StartJournalRecord()
{
// Do not allow recording while playing back
if( Global.fPlaying ) {
MessageBox( GetFocus(), TEXT("Sorry, Currently Playing!"), NULL, MB_OK );
return;
}
// Create journal record file
Global.hFile = OpenFile( (LPCSTR) FILENAME, &Global.OFStruct,
OF_CREATE | OF_WRITE | OF_EXIST );
// Initialize the recorded message count to zero and set recording flag
Global.RecordedMsgCount = 0;
Global.fRecording = TRUE;
// Set the Journal Record hook.
Global.hHookRecord = SetWindowsHookEx( WH_JOURNALRECORD,
JournalRecordProc, Global.hInstance, 0 );
return;
}
// ************************************************************************
// FUNCTION : JournalRecordProc()
// PURPOSE :
// ************************************************************************
LRESULT CALLBACK
JournalRecordProc( int nCode, WPARAM wParam, LPARAM lParam )
{
if( nCode < 0 || Global.fStopRecording )
return( CallNextHookEx( Global.hHookRecord, nCode, wParam, lParam ) );
switch( nCode ) {
case HC_ACTION: {
LPEVENTMSG lpEventMsg;
// write the event message to the Recorded Journal file
Global.hFile = OpenFile( (LPCSTR) FILENAME, &Global.OFStruct,
OF_REOPEN | OF_WRITE );
_llseek( Global.hFile,
(LONG) ( sizeof(EVENTHEADER)
+ (Global.RecordedMsgCount * sizeof(EVENTMSG)) ), 0 );
_lwrite( Global.hFile, (LPCSTR) lParam, sizeof(EVENTMSG) );
_lclose( Global.hFile );
lpEventMsg = (LPEVENTMSG) lParam;
Global.RecordedMsgCount++;
if( Global.RecordedMsgCount == 1)
Global.BaseMsgTime = lpEventMsg->time;
break;
}
case HC_SYSMODALON:
// halt recording
Global.fStopRecording = TRUE;
break;
case HC_SYSMODALOFF:
// resume recording
Global.fStopRecording = FALSE;
break;
}
return( CallNextHookEx( Global.hHookRecord, nCode, wParam, lParam ) );
UNREFERENCED_PARAMETER( wParam );
}
// ************************************************************************
// FUNCTION : StopJournalRecord()
// PURPOSE :
// ************************************************************************
VOID WINAPI
StopJournalRecord()
{
EVENTHEADER EventHeader;
// Remove the Journal Record hook if recording
if( Global.fRecording ) {
UnhookWindowsHookEx( Global.hHookRecord );
// Clear recording flag
Global.fRecording = FALSE;
// Copy Recorded Journal header data to temporary buffer
EventHeader.RecordedMsgCount = Global.RecordedMsgCount;
EventHeader.BaseMsgTime = Global.BaseMsgTime;
// Open Recorded Journal file and update the file header and close
// the file
Global.hFile = OpenFile( (LPCSTR) FILENAME, &Global.OFStruct, OF_WRITE );
_llseek( Global.hFile, 0L, 0 );
_lwrite( Global.hFile, (LPCSTR) &EventHeader, sizeof(EVENTHEADER) );
_lclose( Global.hFile );
}
return;
}
// ************************************************************************
// FUNCTION : StartJournalPlayback()
// PURPOSE :
// ************************************************************************
VOID WINAPI
StartJournalPlayback()
{
EVENTHEADER EventHeader;
// Allow infinite playback loop
if( Global.fRecording ) {
StopJournalRecord();
MessageBox( GetFocus(), TEXT("Infinite Playback Loop Recorded!"),
TEXT("Warning"), MB_ICONEXCLAMATION | MB_OK );
return;
}
// Open Recorded Journal file and read the file header
Global.hFile = OpenFile( (LPCSTR) FILENAME, &Global.OFStruct, OF_READ );
_llseek( Global.hFile, 0L, 0 );
_lread( Global.hFile, (LPVOID) &EventHeader, sizeof(EVENTHEADER) );
_lclose( Global.hFile );
// store the header values
Global.RecordedMsgCount = EventHeader.RecordedMsgCount;
Global.BaseMsgTime = EventHeader.BaseMsgTime;
Global.LastMsgTime = EventHeader.BaseMsgTime;
// If no messages were recorded, none to play back.
if( Global.RecordedMsgCount == 0 ) {
MessageBox( GetFocus(), TEXT("Nothing Recorded!"), NULL, MB_OK);
return;
}
// Initialize the played message count to zero and set the play flag
Global.PlayedMsgCount = 0;
Global.fPlaying = TRUE;
// Get the first recorded message from the file and store it
Global.hFile = OpenFile( (LPCSTR) FILENAME, &Global.OFStruct,
OF_REOPEN | OF_READ );
_llseek( Global.hFile, (LONG) sizeof(EVENTHEADER), 0 );
_lread( Global.hFile, (LPVOID) &(Global.EventMsg), sizeof(EVENTMSG) );
_lclose( Global.hFile );
// Set the Journal Playback hook
Global.hHookPlayback = SetWindowsHookEx( WH_JOURNALPLAYBACK,
JournalPlaybackProc, Global.hInstance, 0 );
return;
}
// ************************************************************************
// FUNCTION : JournalPlaybackProc()
// PURPOSE :
// ************************************************************************
LRESULT CALLBACK
JournalPlaybackProc( int nCode, WPARAM wParam, LPARAM lParam )
{
if( nCode < 0 || Global.fStopPlaying )
return( CallNextHookEx( Global.hHookPlayback, nCode, wParam, lParam ) );
switch( nCode ) {
case HC_GETNEXT: {
LRESULT SleepTime = Global.EventMsg.time - Global.LastMsgTime;
// copy the current ready event message to lParam
CopyMemory( (PVOID) lParam, (CONST VOID*) &(Global.EventMsg),
sizeof(EVENTMSG) );
Global.LastMsgTime = Global.EventMsg.time;
return( SleepTime );
}
case HC_SKIP: {
if( ++Global.PlayedMsgCount > Global.RecordedMsgCount ) {
StopJournalPlayback();
return( (LRESULT) 0L );
}
else {
// Get the next recorded message from the file and store it
// in the static buffer for the next HC_GETNEXT message
Global.hFile = OpenFile( (LPCSTR) FILENAME, &Global.OFStruct,
OF_REOPEN | OF_READ );
_llseek( Global.hFile,
(LONG) ( sizeof(EVENTHEADER)
+ (Global.PlayedMsgCount * sizeof(EVENTMSG)) ), 0 );
_lread( Global.hFile, (LPVOID) &(Global.EventMsg),
sizeof(EVENTMSG) );
_lclose( Global.hFile );
break;
}
}
case HC_SYSMODALON:
// halt playback
Global.fStopPlaying = TRUE;
break;
case HC_SYSMODALOFF:
// resume playback
Global.fStopPlaying = FALSE;
break;
}
return( CallNextHookEx( Global.hHookPlayback, nCode, wParam, lParam ) );
UNREFERENCED_PARAMETER( wParam );
}
// ************************************************************************
// FUNCTION : StopJournalPlayback()
// PURPOSE :
// ************************************************************************
VOID WINAPI
StopJournalPlayback()
{
// Remove the Playback Journal hook if playing
if( Global.fPlaying ) {
UnhookWindowsHookEx( Global.hHookPlayback );
// Clear playback flag
Global.fPlaying = FALSE;
}
return;
}